package com.scuec.groupfive.controller;
import com.scuec.groupfive.dto.PastExamAvgScore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.scuec.groupfive.dto.ExamSubmitDTO;
import com.scuec.groupfive.dto.GenerateExamDTO;
import com.scuec.groupfive.entity.*;
import com.scuec.groupfive.mapper.UserMockMapper;
import com.scuec.groupfive.vo.ExamPaperVO;
import com.scuec.groupfive.vo.ExamResultVO;
import com.scuec.groupfive.vo.QuestionDetailVO;
import com.scuec.groupfive.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.scuec.groupfive.service.ExamService;


import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/exam")
@CrossOrigin(maxAge = 3600)
public class ExamController {
    @Autowired
    private ExamService examService;
    @Autowired
    private UserMockMapper userMockMapper;
    private static final Logger logger = LoggerFactory.getLogger(ExamController.class);

    private Long getMockUserId() {
        return 1L;
    }

    @GetMapping("/info")
    public Map<String, Object> getExamInfo() {
        Map<String, Object> result = new HashMap<>();

        try {
            List<ExamInfo> examInfos = new ArrayList<>();

            examInfos.add(new ExamInfo(
                    "数一",
                    "高等数学、线性代数、概率论与数理统计",
                    "单选题10个(4高数+3线代+3概统,每题5分), 填空题6个(4高数+1线代+1概统,每题5分), 解答题6个(4高数+1线代+1概统)",
                    80,
                    180
            ));

            examInfos.add(new ExamInfo(
                    "数二",
                    "高等数学、线性代数",
                    "单选题10个(7高数+3线代,每题5分), 填空题6个(5高数+1线代,每题5分), 解答题6个(5高数+1线代)",
                    80,
                    180
            ));

            examInfos.add(new ExamInfo(
                    "数三",
                    "高等数学、线性代数、概率论与数理统计",
                    "单选题10个(4高数+3线代+3概统,每题5分), 填空题6个(4高数+1线代+1概统,每题5分), 解答题6个(4高数+2线代+2概统)",
                    80,
                    180
            ));

            result.put("code", 200);
            result.put("msg", "获取考试信息成功");
            result.put("data", examInfos);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "获取考试信息失败: " + e.getMessage());
        }

        return result;
    }

    @GetMapping("/options")
    public Map<String, Object> getExamOptions() {
        Map<String, Object> result = new HashMap<>();

        try {
            List<String> examTypes = Arrays.asList("数一", "数二", "数三");

            List<Map<String, String>> strategies = new ArrayList<>();

            Map<String, String> strategy1 = new HashMap<>();
            strategy1.put("value", "weakness");
            strategy1.put("label", "针对我的薄弱知识点");

            Map<String, String> strategy2 = new HashMap<>();
            strategy2.put("value", "high_frequency");
            strategy2.put("label", "高频易错题");

            Map<String, String> strategy3 = new HashMap<>();
            strategy3.put("value", "random");
            strategy3.put("label", "完全随机");

            Map<String, String> strategy4 = new HashMap<>();
            strategy4.put("value", "custom");
            strategy4.put("label", "定向知识点");

            strategies.add(strategy1);
            strategies.add(strategy2);
            strategies.add(strategy3);
            strategies.add(strategy4);

            result.put("code", 200);
            result.put("msg", "获取组卷选项成功");
            result.put("data", new HashMap<String, Object>() {{
                put("examTypes", examTypes);
                put("strategies", strategies);
            }});
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "获取组卷选项失败: " + e.getMessage());
        }

        return result;
    }

    @PostMapping("/generate")
    public Map<String, Object> generateExam(@RequestBody GenerateExamDTO dto,
                                            @RequestHeader("userId") Long userId) {
        Map<String, Object> result = new HashMap<>();
        try {
            logger.info("收到组卷请求，考试类型: {}, 策略: {}, 用户ID: {}",
                    dto.getExamType(), dto.getStrategy(), userId);

            // 1. 根据考试类型获取标准结构
            ExamStructure structure = getStandardExamStructure(dto.getExamType());
            logger.info("试卷结构: 单选{} 填空{} 主观{}",
                    structure.getSingleChoiceCount(),
                    structure.getFillBlankCount(),
                    structure.getSubjectiveCount());

            // 2. 根据策略生成题目
            List<QuestionInfo> questions;
            switch(dto.getStrategy()) {
                case "random":
                    questions = examService.generateRandomExam(dto.getExamType(), structure, userId);
                    break;
                case "weakness":
                    questions = examService.generateWeaknessExam(dto.getExamType(), structure, userId);
                    break;
                case "high_frequency":
                    questions = examService.generateHighFrequencyExam(dto.getExamType(), structure, userId);
                    break;
                case "custom":
                    logger.info("使用定向知识点策略，知识点: {}", dto.getKnowledgePoints());
                    questions = examService.generateCustomExam(dto.getExamType(), structure, dto.getKnowledgePoints());
                    break;
                default:
                    throw new IllegalArgumentException("不支持的组卷策略");
            }

            // 3. 创建考试记录
            MockExam mockExam = new MockExam();
            mockExam.setUserId(userId);
            mockExam.setExamType(dto.getExamType());
            // 修改后 - 兼容Java 8的实现
            String strategy;
            switch(dto.getStrategy()) {
                case "weakness":
                    strategy = "薄弱知识点";
                    break;
                case "high_frequency":
                    strategy = "高频易错题";
                    break;
                case "random":
                    strategy = "完全随机";
                    break;
                case "custom":
                    strategy = "定向知识点";
                    break;
                default:
                    strategy = "完全随机";
            }
            mockExam.setExamStrategy(strategy);
            mockExam.setTotalQuestions(questions.size());
            mockExam.setTotalTime(dto.getTimeLimit()); // 从 DTO 中获取时间
            mockExam.setScore(0.0); // 初始分数
            userMockMapper.insertMockExam(mockExam);

            // 打印日志，确认mockExam是否成功插入
            logger.info("成功创建模拟考试记录，examId: {}", mockExam.getExamId());
            logger.info("生成的题目数量: {}", questions.size());

            // ==================== 修改点1：同步插入 exam_questions 表 ====================
            // 在生成试卷后，立即将题目数据插入 exam_questions 表，初始状态为未作答
            if (mockExam.getExamId() != null) {
                logger.info("开始插入exam_question记录，examId: {}", mockExam.getExamId());
                for (int i = 0; i < questions.size(); i++) {
                    QuestionInfo question = questions.get(i);
                    ExamQuestion examQuestion = new ExamQuestion();
                    examQuestion.setExamId(mockExam.getExamId());       // 关联考试ID
                    examQuestion.setQuestionId(question.getQuestionId()); // 关联题目ID
                    examQuestion.setSequence(i + 1);                    // 题目序号
                    examQuestion.setQuestionType(question.getQuestionType()); // 题目类型
                    // 初始状态：用户未作答，得分和正确性未知
                    examQuestion.setUserAnswer(null);   // 用户答案（初始为空）
                    examQuestion.setIsCorrect(null);    // 是否正确（初始未知）
                    examQuestion.setScore(null);        // 得分（初始未知）

                    // 打印每条将要插入的记录信息
                    logger.debug("准备插入exam_question记录 - examId: {}, questionId: {}, sequence: {}, questionType: {}",
                            examQuestion.getExamId(), examQuestion.getQuestionId(),
                            examQuestion.getSequence(), examQuestion.getQuestionType());

                    try {
                        int rowsAffected = userMockMapper.insertExamQuestion(examQuestion);
                        logger.debug("插入exam_question记录结果 - examId: {}, questionId: {}, 影响行数: {}",
                                examQuestion.getExamId(), examQuestion.getQuestionId(), rowsAffected);
                    } catch (Exception e) {
                        logger.error("插入exam_question记录失败 - examId: {}, questionId: {}, 错误: {}",
                                examQuestion.getExamId(), examQuestion.getQuestionId(), e.getMessage(), e);
                        throw e; // 抛出异常，让外层捕获
                    }
                }
                logger.info("完成插入exam_question记录，共插入{}条记录", questions.size());
            } else {
                logger.error("创建考试记录后获取到的examId为null，无法插入exam_question记录");
            }
            // ==================== 修改点1结束 ====================

            result.put("code", 200);
            result.put("msg", "组卷成功");
            Map<String, Object> data = new HashMap<>();
            data.put("examId", mockExam.getExamId());
            result.put("data", data);
        } catch (Exception e) {
            // 打印完整的异常堆栈
            logger.error("组卷过程中发生错误: ", e);
            result.put("code", 500);
            result.put("msg", "组卷失败: " + e.getMessage());
        }
        return result;
    }


    @GetMapping("/knowledge-points")
    public Map<String, Object> getKnowledgePoints(@RequestParam String examType) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 1. 根据考试类型获取科目ID
            List<Integer> subjectIds = examService.getSubjectIdsByExamType(examType);

            // 2. 获取这些科目下的所有知识点（服务层已过滤）
            List<KnowledgePoint> knowledgePoints = examService.getKnowledgePointsBySubjects(subjectIds);

            // 3. 按科目分组返回
            Map<Integer, List<KnowledgePoint>> groupedPoints = knowledgePoints.stream()
                    .collect(Collectors.groupingBy(KnowledgePoint::getSubjectId));

            result.put("code", 200);
            result.put("msg", "获取知识点列表成功");
            result.put("data", new HashMap<String, Object>() {{
                put("knowledgePoints", knowledgePoints);
                put("groupedPoints", groupedPoints);
            }});
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "获取知识点列表失败: " + e.getMessage());
        }
        return result;
    }

    private ExamStructure getExamStructure(String examType) {
        ExamStructure structure = new ExamStructure();

        switch(examType) {
            case "数一":
                structure.setSingleChoiceCount(10);
                structure.setFillBlankCount(6);
                structure.setSubjectiveCount(6);
                structure.setTimeLimit(180);
                break;
            case "数二":
                structure.setSingleChoiceCount(10);
                structure.setFillBlankCount(6);
                structure.setSubjectiveCount(6);
                structure.setTimeLimit(180);
                break;
            case "数三":
                structure.setSingleChoiceCount(10);
                structure.setFillBlankCount(6);
                structure.setSubjectiveCount(8); // 修改数三主观题数量为8
                structure.setTimeLimit(180);
                break;
            default:
                throw new IllegalArgumentException("不支持的考试类型");
        }

        return structure;
    }

    private List<QuestionInfo> generateMockQuestions(String examType, ExamStructure structure, String strategy) {
        List<QuestionInfo> questions = new ArrayList<>();
        Random random = new Random();

        for (int i = 1; i <= structure.getSingleChoiceCount(); i++) {
            QuestionInfo question = new QuestionInfo();
            question.setQuestionId((long) i);
            question.setQuestionType("single_choice");
            question.setContent("单选题示例 " + i + " (考试类型: " + examType + ", 策略: " + strategy + ")");
            question.setOptions(Arrays.asList("选项A", "选项B", "选项C", "选项D").toString());
            question.setAnswer("选项" + (char)('A' + random.nextInt(4)));
            questions.add(question);
        }

        for (int i = 1; i <= structure.getFillBlankCount(); i++) {
            QuestionInfo question = new QuestionInfo();
            question.setQuestionId((long) (i + structure.getSingleChoiceCount()));
            question.setQuestionType("fill_blank");
            question.setContent("填空题示例 " + i + " (考试类型: " + examType + ", 策略: " + strategy + ")");
            question.setAnswer("答案" + (i + 10));
            questions.add(question);
        }

        for (int i = 1; i <= structure.getSubjectiveCount(); i++) {
            QuestionInfo question = new QuestionInfo();
            question.setQuestionId((long) (i + structure.getSingleChoiceCount() + structure.getFillBlankCount()));
            question.setQuestionType("subjective");
            question.setContent("主观题示例 " + i + " (考试类型: " + examType + ", 策略: " + strategy + ")");
            question.setAnswer("参考答案" + (i + 20));
            questions.add(question);
        }

        return questions;
    }

    private ExamStructure getExamStructureByType(String examType) {
        ExamStructure structure = new ExamStructure();
        if ("数一".equals(examType)) {
            structure.setSingleChoiceCount(10);
            structure.setFillBlankCount(6);
            structure.setSubjectiveCount(6);
        } else if ("数二".equals(examType)) {
            structure.setSingleChoiceCount(10);
            structure.setFillBlankCount(6);
            structure.setSubjectiveCount(6);
        } else if ("数三".equals(examType)) {
            structure.setSingleChoiceCount(10);
            structure.setFillBlankCount(6);
            structure.setSubjectiveCount(8); // 修改数三主观题数量为8
        }
        return structure;
    }

    /**
     * 根据题目ID获取题目详情
     * @param questionId 题目ID
     * @return 题目详情
     */
    @GetMapping("/question/{questionId}")
    public Result<QuestionDetailVO> getQuestionDetail(@PathVariable("questionId") Long questionId) {
        QuestionDetailVO questionDetail = examService.getQuestionDetail(questionId);
        return Result.success(questionDetail);
    }

    /**
     * 提交考试
     * 修改点2：不再直接操作 exam_questions 表（由 Service 层处理）
     */
    @PostMapping("/submit")
    public Map<String, Object> submitExam(@RequestBody ExamSubmitDTO examSubmitDTO,
                                          @RequestHeader("userId") Long userId) {
        Map<String, Object> result = new HashMap<>();
        try {
            ExamResultVO examResult = examSubmitDTO.getIsPastExam() ?
                    examService.submitPastExam(examSubmitDTO, userId) :
                    examService.submitExam(examSubmitDTO, userId);

            result.put("code", 200);
            result.put("msg", "提交成功");
            result.put("data", examResult);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "提交失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 根据考试ID获取整套试卷题目
     * @param examId 考试ID
     * @return 考试试卷VO
     */
    @GetMapping("/{examId}/questions")
    public Result<ExamPaperVO> getExamQuestions(@PathVariable Long examId) {

        ExamPaperVO examPaper = examService.getExamPaperByExamId(examId);
        return Result.success(examPaper);
    }

    /**
     * 获取题目详情（新路径）
     * @param questionId 题目ID
     * @return 题目详情VO
     */
    @GetMapping("/questions/{questionId}")
    public Result<QuestionDetailVO> getQuestionDetailById(@PathVariable Long questionId) {
        QuestionDetailVO questionDetail = examService.getQuestionDetail(questionId);
        return Result.success(questionDetail);
    }

    /**
     * 获取考试详情
     * 修改点3：从 exam_questions 表查询数据（而非 answer_records 表）
     */
    @GetMapping("/detail/{examId}")
    public Map<String, Object> getExamDetail(@PathVariable Long examId) {
        Map<String, Object> result = new HashMap<>();
        try {
            // ==================== 修改点3：从 exam_questions 表查询考试详情 ====================
            // 原本可能从 answer_records 表查询，现在改为从 exam_questions 表获取
            // 因为 exam_questions 表已经存储了用户作答情况和得分
            Map<String, Object> examDetail = examService.getExamDetail(examId);
            // ==================== 修改点3结束 ====================

            result.put("code", 200);
            result.put("msg", "查询成功");
            result.put("data", examDetail);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "查询失败: " + e.getMessage());
        }
        return result;
    }
    // 新增方法：获取标准考试结构
    private ExamStructure getStandardExamStructure(String examType) {
        ExamStructure structure = new ExamStructure();
        if ("数三".equals(examType)) {
            structure.setSingleChoiceCount(10);
            structure.setFillBlankCount(6);
            structure.setSubjectiveCount(8);
        } else {
            structure.setSingleChoiceCount(10);
            structure.setFillBlankCount(6);
            structure.setSubjectiveCount(6);
        }
        return structure;
    }
    //--------------------------------------------------------------------------
    //-----------------------------历年套卷---------------------------------------
    //--------------------------------------------------------------------------
    /**
     * 获取历年套卷列表
     * @param examType 考试类型(数一/数二/数三)
     * @param year 年份
     * @return 历年套卷列表
     */
    @GetMapping("/past-exams")
    public Map<String, Object> getPastExamRecords(
            @RequestParam String examType,
            @RequestParam int year) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<PastExamRecord> records = examService.getPastExamRecords(examType, year);
            result.put("code", 200);
            result.put("msg", "获取历年套卷列表成功");
            result.put("data", records);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "获取历年套卷列表失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 获取历年套卷统计数据
     */
    // ExamController.java

    @GetMapping("/past-exams/stats")
    public Map<String, Object> getPastExamStats(@RequestParam(required = false) Integer year) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 1. 获取所有存在的套卷（按年份和类型分组）
            List<PastExamPaper> allPapers = examService.getAllPastExamPapers();

            // 2. 获取当前用户ID
            Long userId = getCurrentUserId();

            // 3. 获取用户参加过的考试统计 - 确保正确统计
            List<PastExamStat> myExamCounts = userId != null ?
                    userMockMapper.countMyPastExams(userId) :
                    Collections.emptyList();

            // 4. 获取所有考试的平均分数据
            List<PastExamAvgScore> avgScores = userMockMapper.getPastExamAvgScores();

            // 创建查找映射
            Map<String, Integer> countMap = myExamCounts.stream()
                    .collect(Collectors.toMap(
                            stat -> stat.getExamYear() + "_" + stat.getExamType(),
                            PastExamStat::getExamCount
                    ));

            // 创建平均分查找映射
            Map<String, Double> avgScoreMap = avgScores.stream()
                    .collect(Collectors.toMap(
                            score -> score.getExamYear() + "_" + score.getExamType(),
                            PastExamAvgScore::getAvgScore
                    ));

            // 5. 组合数据
            List<Map<String, Object>> examData = allPapers.stream()
                    .map(paper -> {
                        String key = paper.getExamYear() + "_" + paper.getExamType();
                        Integer count = countMap.get(key);
                        Double avgScore = avgScoreMap.get(key);

                        Map<String, Object> item = new HashMap<>();
                        item.put("examYear", paper.getExamYear());
                        item.put("examType", paper.getExamType());
                        item.put("totalQuestions", paper.getTotalQuestions());
                        item.put("myExamCount", count != null ? count : 0);
                        item.put("avgScore", avgScore != null ? avgScore : 0.0); // 添加平均分
                        return item;
                    })
                    .collect(Collectors.toList());

            result.put("code", 200);
            result.put("msg", "获取历年套卷数据成功");
            result.put("data", examData);
        } catch (Exception e) {
            logger.error("获取历年套卷数据失败", e);
            result.put("code", 500);
            result.put("msg", "获取历年套卷数据失败: " + e.getMessage());
        }
        return result;
    }
    // 添加获取当前用户ID的方法
    private Long getCurrentUserId() {
        // 这里根据您的认证系统实现获取当前用户ID
        // 例如使用Spring Security:
        // return SecurityContextHolder.getContext().getAuthentication().getName();
        return 1L; // 临时返回固定值，实际项目中需要替换
    }
    /**
     * 获取历年真题试卷题目
     * @param examType 考试类型(数一/数二/数三)
     * @param year 年份
     * @return 题目列表
     */
    @GetMapping("/past-exam-questions")
    public Map<String, Object> getPastExamQuestions(
            @RequestParam String examType,
            @RequestParam int year) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<QuestionInfo> questions = examService.getPastExamQuestions(examType, year);

            // 设置题目序号
            for (int i = 0; i < questions.size(); i++) {
                questions.get(i).setSequence(i + 1);
            }

            result.put("code", 200);
            result.put("msg", "获取历年真题试卷成功");
            result.put("data", questions);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "获取历年真题试卷失败: " + e.getMessage());
        }
        return result;
    }
    @GetMapping("/past-exams/detail/{recordId}")
    public Map<String, Object> getPastExamDetail(@PathVariable Long recordId) {
        return examService.getPastExamDetail(recordId);
    }
}